/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.yonsei.iwb.smarttv.gui;

import com.hp.hpl.jena.query.Query;
import com.hp.hpl.jena.query.QueryFactory;
import edu.yonsei.iwb.smarttv.LocalOntologySearch;
import edu.yonsei.iwb.smarttv.LocalOntologySearchInterface;
import edu.yonsei.iwb.smarttv.index.IndexType;
import edu.yonsei.iwb.smarttv.index.OntologyIndexer;
import edu.yonsei.iwb.smarttv.jena.ext.JenaModelType;
import edu.yonsei.iwb.smarttv.model.ConceptualGraph;
import edu.yonsei.iwb.smarttv.model.SMARTTVModel;
import edu.yonsei.iwb.smarttv.query.HanNanumMorphemeTag;
import edu.yonsei.iwb.smarttv.query.TermAnalyzer;
import edu.yonsei.iwb.smarttv.querygraph.DynamicSPARQLGenerator;
import edu.yonsei.iwb.smarttv.querygraph.algorithm.ShortestPathVectorCandidateSet;
import edu.yonsei.iwb.smarttv.result.*;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JPanel;
import kr.ac.kaist.swrc.jhannanum.comm.Eojeol;
import kr.ac.kaist.swrc.jhannanum.exception.ResultTypeException;

/**
 *
 * @author Soo
 */
public class Controller {
    private String ontology;
    private SMARTTVModel tvModel;
    private OntologyIndexer oi;
    private LocalOntologySearchInterface losi;
    private String query;
    private TermAnalyzer ta;
    private NERResults ner;
    private DynamicSPARQLGenerator dsg;
    private ShortestPathVectorCandidateSet spvcs;
    private Vector<String> sparqlSet;
    
    
    public void selectOntFile(String ontology){
        this.ontology = ontology;
    }

    public void loadOntOnTDB(String directory) {
        JenaModelType.MODEL_DIR = directory;
        tvModel = new SMARTTVModel(JenaModelType.TDB_MODEL);
        tvModel.loadOntology(ontology);
    }

    public void useTDBModel(String directory) {
        JenaModelType.MODEL_DIR = directory;
        tvModel = new SMARTTVModel(JenaModelType.TDB_MODEL);
        tvModel.loadOntology(ontology); // 온톨로지 파일을 선택하지 않고, tdb 파일 사용했을 경우, 이 부분에서 에러남. ontology가 null이기 때문.
    }
    
    public void loadOntOnMemory(){
        tvModel = new SMARTTVModel(JenaModelType.MEMORY_MODEL);
        tvModel.loadOntology(ontology);
    }
    
    public void loadIndexOnMemory(){
        oi = new OntologyIndexer(IndexType.MEMORY_INDEX, tvModel);
        losi = new LocalOntologySearch(tvModel, oi.getIndex());
    }
    
    public void loadIndexInDir(String directory) {
        IndexType.INDEX_DIR = directory;
        oi = new OntologyIndexer(IndexType.FILE_INDEX, tvModel);
        losi = new LocalOntologySearch(tvModel, oi.getIndex());
    }
    
    public void useFileIndex(String directory) {
        IndexType.INDEX_DIR = directory;
        losi = new LocalOntologySearch(tvModel);
    }
    
    public Vector<String[]> getMAResult(String query) {
        
        this.query = query;
        Vector<String[]> maVector = new Vector<String[]>();
        ta = new TermAnalyzer();
        Eojeol[] maResult;
        try {
            maResult = ta.getEojeol(this.query);
            for (int i = 0; i < maResult.length; i++) {
                if (maResult[i].length > 0) {
                    String[] morphemes = maResult[i].getMorphemes();
                    String[] tags = maResult[i].getTags();
                    for (int j = 0; j < morphemes.length; j++) {
                        if (HanNanumMorphemeTag.useMorpheme(tags[j])) {
                            String[] s ={morphemes[j].toLowerCase(), tags[j]};
                            maVector.add(s);
                        }
                    }
                }
            }
        } catch (ResultTypeException ex) {
            Logger.getLogger(Controller.class.getName()).log(Level.SEVERE, null, ex);
        }
        ta.deactivateWorkflow();
        return maVector;
    }
    
    public Vector<String[]> getNERResult(){        
        
        Vector<String[]> nerVector = new Vector<String[]>();
        ner = losi.recognizeNamedEntity(query);
        NamedEntityLinkedHashMap nelhm = ner.getNamedEntityResults();
        Iterator<String> keyIterator = nelhm.keySet().iterator();
        while (keyIterator.hasNext()) {
            String key = keyIterator.next();
            NamedEntitySet nes = ner.getNamedEntitySetByString(key);
            for (int i = 0; i < nes.size(); i++) {
                NamedEntity ne = nes.get(i);
                ResultTypeInfo rti = ne.getResultTypes();
                for (int j = 0; j < rti.size(); j++) {
                    ResultNode resultNode = rti.get(j);
                    String keyword = key;
                    String[] uri =  ne.getNamedEntityNodeId().split("/");
                    String lastUri = uri[uri.length-1];
                    String label = ne.getNamedEntityNodeLabel();                    
                    String[] typeUri = resultNode.getResultNodeId().split("/");
                    String lastTypeUri = typeUri[typeUri.length-1];
                    String[] s ={keyword, lastUri, label, lastTypeUri};
                    nerVector.add(s);
                }
            }
        }
        return nerVector;
    }

    public Vector<JPanel> getConceptualGraphViewSet() {
        dsg = new DynamicSPARQLGenerator(tvModel);
        spvcs = dsg.dynamicSPARQLGenerator(ner);
        Vector<ConceptualGraph> conceptualGraphSet = dsg.getConceptualGraphSet();
        ConceptualGraphView cgv = new ConceptualGraphView(conceptualGraphSet);
        Vector<JPanel> conceptualGraphView = cgv.generateConceptualGraphView();
        
        return conceptualGraphView;
        
    }
    
    public Vector<JPanel> getSpanningTreeViewSet(){
        SpanningTreeView stv = new SpanningTreeView(spvcs);
        Vector<JPanel> spanningTreeView = stv.generateSpanningTreeView();
        return spanningTreeView;
    }

    public Vector<JPanel> getShortestPathViewSet(){
        ShortestPathView spv = new ShortestPathView(spvcs);
        Vector<JPanel> shortestPathView = spv.generateShortestPathView();
        return shortestPathView;
    }
    
    public Vector<String> getSPARQLViewSet(){
        sparqlSet = new Vector<String>();
        for(int i = 0; i < spvcs.size(); i++){
            Query query = dsg.generateSPARQL(spvcs.get(i));
            String sparql = query.serialize();
            sparqlSet.add(sparql);
        }
        return sparqlSet;        
    }
    
    public Vector<String[]> getSearchResult(){
        Vector<String[]> searchResultVector = new Vector<String[]>();
        String sparql = sparqlSet.firstElement();
        searchResultVector = getSearchResultBySPARQL(sparql);
        return searchResultVector;
    }
    
    public Vector<String[]> getSearchResultBySelectedQuery(String sparqlQuery){
        
        Vector<String[]> searchResultVector = new Vector<String[]>();
        searchResultVector = getSearchResultBySPARQL(sparqlQuery);
        return searchResultVector;
    }
    
    public Vector<String[]> getSearchResultBySPARQL(String sparqlQuery){
        Vector<String[]> searchResultVector = new Vector<String[]>();
        Query query = QueryFactory.create(sparqlQuery);
        Vector<SearchResultSet> srs = losi.getSearchResult(query);
        for(int i = 0; i < srs.size(); i++){
            String title = srs.get(i).getResultLabel();
            String type = "";
            ResultTypeInfo types = srs.get(i).getResultTypes();
            for(int j = 0; j < types.size(); j++){
                String t = types.get(j).getLabel();
                if(j!=types.size()-1){
                    type += t+"/";
                }else{
                    type += t;
                }
            }
            String[] s ={Integer.toString(i+1), title, type};
            searchResultVector.add(s);
        }
        return searchResultVector;
    }
    
}
